package org.csu.sei.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.csu.sei.common.BaseConstant;
import org.csu.sei.common.PageRes;
import org.csu.sei.entity.*;
import org.csu.sei.entity.DTO.FrontTeacherInfoItemDTO;
import org.csu.sei.entity.DTO.MonCount;
import org.csu.sei.entity.DTO.NewsDTO;
import org.csu.sei.persistence.*;
import org.csu.sei.service.INewsContentService;
import org.csu.sei.service.INewsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.time.LocalDateTime;

@Component(value = "newsService")
public class NewsServiceimpl extends ServiceImpl<NewsMapper, News> implements INewsService {

    @Resource
    private NewsMapper newsMapper;

    @Resource
    private INewsContentService newsContentService;

    @Resource
    private TeacherInfoMapper teacherInfoMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private StatisticsMapper statisticsMapper;

    private static final Logger logger = LoggerFactory.getLogger(NewsServiceimpl.class);


    @Override
    public News queryNews(Long id) {
        return newsMapper.selectById(id);
    }

    @Override
    public Long insertNews(News news) {
        news.setCount(0);
        news.setListOrder(0);
        if(categoryMapper.selectList(new QueryWrapper<Category>().eq("parent_id",news.getCatId())).size()>0){
            return Long.parseLong("-5");
        }
        news.setCreateTime(LocalDateTime.now());
        news.setUpdateTime(LocalDateTime.now());
        newsMapper.insert(news);
        return news.getId();
    }

    @Override
    public int deleteNews(Long id) {
        newsContentService.deleteByNewsId(id);
        return newsMapper.deleteById(id);
    }

    //更新news的同时，更新其updatetime
    @Override
    public int  updateNewsAndContent(News news,NewsContent newsContent) {
        news.setUpdateTime(LocalDateTime.now());
        newsContent.setUpdateTime(LocalDateTime.now());
        newsContentService.updateNewsContent(newsContent);
        return newsMapper.updateById(news);
    }

    @Override
    public PageRes querySameCategoryNews(Long catId,int page,int limit,boolean selectInviable){
        IPage<News> newsPage = new Page<>(page,limit);
        QueryWrapper<News> queryWrapper=new QueryWrapper<>();
        if (selectInviable){
            queryWrapper.eq("cat_id",catId);
        }
        else{
            queryWrapper.eq("cat_id",catId)
                    .eq("news_status",1);
        }
        queryWrapper.orderBy(true,false,"list_order","update_time");
        List<News> newsList = newsMapper.selectPage(newsPage,queryWrapper).getRecords();
        int count = newsMapper.selectCount(queryWrapper);

        return new PageRes(page+1 , limit, count, (int)count /limit+1 , newsList);
    }

    @Override
    public PageRes queryNewsByName(String name, int page, int limit,boolean selectInvisible) {
        IPage<News> newsPage = new Page<>(page,limit);
        QueryWrapper<News> queryWrapper=new QueryWrapper<>();
        if (selectInvisible){
            queryWrapper.like("title",name);
        }
        else{
            queryWrapper.like("title",name)
                    .eq("news_status",1);
        }
        queryWrapper.orderBy(true,false,"list_order","update_time");
        List<News> newsList = newsMapper.selectPage(newsPage,queryWrapper).getRecords();
        int count = newsMapper.selectCount(queryWrapper);
        return new PageRes(page+1 , limit, count, (int)count /limit+1 , newsList);
    }

    @Override
    public void changeStatus(Long id) {
        News news = this.queryNews(id);
        if(news.getNewsStatus()== BaseConstant.Status.INVISIBLE.getCode()){
            news.setNewsStatus(BaseConstant.Status.VISIBLE.getCode());
        }
        else{
            news.setNewsStatus(BaseConstant.Status.INVISIBLE.getCode());
        }
        newsMapper.updateById(news);
    }

    @Override
    @Transactional(readOnly = false)
    public int insertNewsAndContent(News news, NewsContent newsContent) {
        Long catId=news.getCatId();
        //在category中寻找父类型id为catId的类型，存在则说明不是叶子节点
        if(categoryMapper.selectCount(new QueryWrapper<Category>().eq("parent_id",catId))>0){
            return -5;
        }
        logger.info(news.toString());
        logger.info(newsContent.toString());
        news.setListOrder(1);
        Long id = insertNews(news);
        newsContent.setNewsId(id);
        return newsContentService.insertNewsContent(newsContent);
    }

    @Override
    public JSONObject queryLatestNews(int page, int limit,boolean selectInvisible) {
        QueryWrapper<News> newsQueryWrapper = new QueryWrapper<>();
        IPage<News> newsPage = new Page<>(page,limit);
        newsQueryWrapper.ge("update_time",LocalDateTime.now().minusDays(30));
        if(selectInvisible){
            newsQueryWrapper.orderBy(true,false,"update_time");
        }
        else{
            newsQueryWrapper.eq("news_status",1)
                    .orderBy(true,false,"update_time");
        }
        newsPage=newsMapper.selectPage(newsPage,newsQueryWrapper);
        int totalSize = newsMapper.selectCount(newsQueryWrapper);
        IPage<News> timeDatePage = new Page<>(1,1);
        timeDatePage=newsMapper.selectPage(timeDatePage,new QueryWrapper<News>().orderByDesc("update_time"));
        LocalDateTime time = timeDatePage.getRecords().get(0).getUpdateTime();
        DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String timeStr=dateFormat.format(time);

        JSONObject json = new JSONObject();
        json.put("page_res",new PageRes(page+1,limit,totalSize,(int)totalSize /limit+1,newsPage.getRecords()));
        json.put("recentUpdateTime",timeStr);
        return json;
    }

    @Override
    public JSONObject queryTeacherInfoList(){
        List<String> jobTitleList = BaseConstant.JobTitle.getEumValueList();
        JSONObject object = new JSONObject();
        JSONArray staffList = new JSONArray();
        for (String jobTitle:jobTitleList){
            JSONObject json = new JSONObject();
            json.put("jobTitle",jobTitle);
            json.put("teacherList",queryTeacherInfoByJobTitle(jobTitle));
            staffList.add(json);
        }
        object.put("staffList",staffList);
        return object;
    }

    private List<FrontTeacherInfoItemDTO> queryTeacherInfoByJobTitle(String jobTitle){
        QueryWrapper<TeacherInfo> queryWrapper = new QueryWrapper();
        queryWrapper.eq("job_title",jobTitle);
        List<TeacherInfo> teacherInfos= teacherInfoMapper.selectList(queryWrapper);
        List<FrontTeacherInfoItemDTO> teacherInfoItemDTOS = new ArrayList<>();
        for (TeacherInfo teacherInfo : teacherInfos) {
            teacherInfoItemDTOS.add(FrontTeacherInfoItemDTO.returnFrontTeacherInfoItem(teacherInfo));
            System.out.println(FrontTeacherInfoItemDTO.returnFrontTeacherInfoItem(teacherInfo));
        }
        System.out.println(teacherInfoItemDTOS.size());
        return teacherInfoItemDTOS;
    }

    @Override
    public int deleteSome(List<Long> idList) {
        int count = 0;
        for (Long id : idList){
            count = count + deleteNews(id);
        }
        return count;
    }

    @Override
    public int setLook(List<Long> idList, int status) {
        for (Long id : idList) {
            News news = newsMapper.selectById(id);
            news.setNewsStatus(status);
            newsMapper.updateById(news);
        }
        return 1;
    }
    @Override
    public PageRes queryNewsListBySomeCondition(int page,int limit,List<Long> catId,String title,List<Integer> status,Long newsId){
        IPage<News> newsIPage = new Page<>(page,limit);
        QueryWrapper<News> queryWrapper= new QueryWrapper<>();
        boolean haveCondition = false;
        if(catId!=null && catId.size()>0){
            queryWrapper.and(queryWrapper1 -> {for (Long id : catId) {
                queryWrapper1.eq("cat_id",id).or();
            }});
            haveCondition = true;
        }
        if(!StringUtils.isEmpty(title)){
            queryWrapper.like("title",title);
            haveCondition = true;
        }
        if(status!=null && status.size()>0)
        {
            queryWrapper.and(queryWrapper1 -> {for (int s : status) {
                queryWrapper1.eq("news_status",s).or();
            }});
            haveCondition = true;
        }
        if(newsId!=null){
            queryWrapper.eq("id",newsId);
        }
        queryWrapper.orderBy(true,false,"list_order","update_time");
        newsIPage = newsMapper.selectPage(newsIPage,haveCondition?queryWrapper:queryWrapper.ne("id",-1));
        int count = newsMapper.selectCount(queryWrapper);
        List<News>  newsList = newsIPage.getRecords();
        List<NewsDTO> newsDTOList = new ArrayList<>();
        for (News news: newsList) {
            String catName=categoryMapper.getName(news.getCatId());
            NewsDTO newsDTO = NewsDTO.returnNews(news,catName);
            System.out.println(newsDTO.toString());
            newsDTOList.add(newsDTO);
        }
        return new PageRes(page+1 , limit, count, (int)count /limit+1 ,newsDTOList);
    }

    @Override
    public int changeOrder(Long id,int order){
     News news = newsMapper.selectById(id);
     if(news == null){
         return -1;
     }
     if(order<0){
         return -2;
     }
     news.setListOrder(order);
     newsMapper.updateById(news);
     return 0;
    }

    @Override
    public void countReader(Long id) {
        News news = newsMapper.selectById(id);
        news.setCount(news.getCount()+1);
        newsMapper.updateById(news);

        Calendar cal = Calendar.getInstance();

        int year = cal.get(Calendar.YEAR);
        int mon = cal.get(Calendar.MONTH) + 1;
        long newsId = id;
        QueryWrapper<Statistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year",year).eq("mon",mon).eq("news_id",newsId);
        Statistics statistics = statisticsMapper.selectOne(queryWrapper);
        if(statistics == null || statistics.getYear() == 0){//没有相关记录则插入
            statistics = new Statistics();
            statistics.setYear(year);
            statistics.setMon(mon);
            statistics.setNewsId(newsId);
            statistics.setCountNum(1);
            System.out.println("year"+statistics.getYear()+"mon"+statistics.getMon()+"count"+statistics.getCountNum());
            statisticsMapper.insert(statistics);
        }else {
            statistics.setCountNum(statistics.getCountNum() + 1);
            System.out.println(statistics.getYear());
            statisticsMapper.update(statistics,queryWrapper);
        }
    }

    @Override
    public int getCount(){
        return newsMapper.selectCount(null);
    }



}
